/**
 * @author shaosong
 * @description
 */
import { formatNavItem, Title } from '@/lib/nav/format-nav-item'
import { Anchor } from 'antd'
import { useTheme } from 'next-themes'
import React, { useCallback, useEffect, useState } from 'react'

export class NavAnchorProps {
  sourceMd: string | undefined
  id!: string | ''
}

const NavAnchor: React.FC<NavAnchorProps> = ({ sourceMd, id }) => {
  const { theme } = useTheme()

  const [titles, changeTitles] = useState<Title[]>()

  const addAnchor = useCallback(() => {
    const container = document.getElementById(id)
    // 获取markdown标题的dom节点
    const header: NodeListOf<HTMLElement> = container?.querySelectorAll(
      'h1, h2, h3, h4, h5, h6'
    )
    // 向标题中注入id，用于锚点跳转
    header?.forEach((navItem, index) => {
      navItem.setAttribute('id', navItem.innerHTML)
    })
    // 格式化标题数组，用于antd锚点组件自动生成锚点
    let titles = formatNavItem(header)
    return titles
  }, [id])

  useEffect(() => {
    if (sourceMd && id) {
      changeTitles(addAnchor())
    }
  }, [sourceMd, id, addAnchor])

  /**
   * 锚点item点击事件
   * 1.解决antd的Anchor组件会在导航栏显示"#锚点id"的问题，
   * 2.以及本项目中navbar通过监听屏幕滚动进行定位，通过scrollIntoView设置页面滚动缓冲，可以一定程度上解决在页面快速滚动时navbar的定位切换造成的闪烁问题。
   * 当然也可以不设置该点击事件
   */
  const handleClickNavItem = (e: any, link: any) => {
    e.preventDefault()
    if (link.href) {
      // 找到锚点对应得的节点
      let element = document.getElementById(link.href)
      // 如果对应id的锚点存在，就跳滚动到锚点顶部
      element && element.scrollIntoView({ block: 'start', behavior: 'smooth' })
    }
  }

  useEffect(() => {
    if (titles?.length > 0 && location.hash) {
      let element = document.getElementById(location.hash)
      // 如果对应id的锚点存在，就跳滚动到锚点顶部
      element && element.scrollIntoView({ block: 'start', behavior: 'smooth' })
    }
  }, [titles])

  return React.useMemo(
    () => (
      <Anchor
        showInkInFixed
        className="markdown-nav dark:hover:text-gray-300 dark:text-white"
        affix
        replace
        offsetTop={100} // 设置距离页面顶部的偏移
        onClick={handleClickNavItem}
        items={titles}
      />
    ),
    [titles]
  )
}

export default NavAnchor
